﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Navigation;
using System.Diagnostics;
using System.Text.RegularExpressions;
// ColorPicker, Copyright Mirosław M. Mączka.  All Rights Reserved. This code released under the terms of the Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.)

namespace ColorPicker
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded_1(object sender, RoutedEventArgs e)
        {
            laoadAllColors("");
            //
            //double buttonSide = (double)window1.FindResource("buttonSide");
            //
        }

        private void laoadAllColors(string pattern)
        {
            List<ColorsCooked> src = CColors.ColorsTable;
            Regex r=null;
            //
            //
            bool isInvalidPattern = false;
            if ("" != pattern)
            {
                if (pattern.StartsWith("#"))// próba wyszukania po wartosci
                {
                    uint u;
                    if (uint.TryParse(pattern.Substring(1), System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out u))
                    {
                        src = (from y in CColors.ColorsTable where y.ColorRGB == u select y).ToList<ColorsCooked>();
                    }
                    else isInvalidPattern = true;
                }
                //
                if (!pattern.StartsWith("#") || isInvalidPattern)// błędny format po `#', albo szukanie po nazwie
                {
                    r = new Regex(pattern, RegexOptions.IgnoreCase);
                    src = (from y in CColors.ColorsTable where y.ColorNames.Any(v => r.Match(v.Name).Success) select y).ToList<ColorsCooked>();
                }
            }
            //
            //var x = from y in  CColors.ColorsTable where y.ColorNames.Any(v => v.Name == pattern) select y;
            //var x = from y in CColors.ColorsTable where y.ColorNames.Any(v => r.Match(v.Name).Success) select y;
            window1.IsEnabled = false;
            panel1.Children.Clear();
            foreach (ColorsCooked c in src)
            {
                //
                UCbutton b = new UCbutton();
                b.ContextMenu = FindResource("ButtonContextMenu") as ContextMenu;
                //TextBox b = new TextBox();
                string cn = "";
                foreach (ColorNameWithSource cnws in c.ColorNames)
                {
                    cn += string.Format("{0}({1})\n", cnws.Name, cnws.Source);
                }
                cn = cn.TrimEnd();
                //
                b.ToolTip = string.Format("{0}\n{1}/{2}/{3}", cn, c.ColorR, c.ColorG, c.ColorB);
                b.EssentialColor = c;
                b.Tag = (object)c;
                //
                //
                //
                panel1.Children.Add(b);
            }
            window1.IsEnabled = true;
        }

        enum OutputFormat { FromKbd, CS, ColorXAML, BrushXAML, ColorHTML}
        private string lck2String(List<ColorsCooked> lck, OutputFormat of)
        {
            if (OutputFormat.FromKbd == of)
            {
                if (Keyboard.Modifiers == ModifierKeys.None)
                {
                    of = OutputFormat.CS;
                }
                else if (Keyboard.Modifiers == ModifierKeys.Shift)
                {
                    of = OutputFormat.ColorXAML;
                }
                else if (Keyboard.Modifiers == ModifierKeys.Control)
                {
                    of = OutputFormat.BrushXAML;
                }
                else if (Keyboard.Modifiers == ModifierKeys.Alt)
                {
                    of = OutputFormat.ColorHTML;
                }
            }
            //
            string s = "";
            if (OutputFormat.CS == of)
            {
                s = getColorCS(lck);
            }
            else if (OutputFormat.ColorXAML == of)
            {
                s = getColorXAML(lck);
            }
            else if (OutputFormat.BrushXAML == of)
            {
                s = getBrushXAML(lck);
            }
            else if (OutputFormat.ColorHTML == of)
            {
                s = getColorHTML(lck);
            }
            return s;
        }

        private enum ColorKind :int{ Usual = 0, Complement = 1, Monochrome = 2, Triadic = 3, Analogous=4,SplitComplements=5 };

        private void add2LckColor(List<ColorsCooked> lck, ColorsCooked cc, int colorKind)
        {
            switch (colorKind)
            {
                case 0://Color As usual
                    lck.Add(cc);
                    break;
                case 1://Complement Color
                    lck.Add(ColorRGB.ColorRGB2ColorCooked(CColorManipulations.GetComplementColor(ColorRGB.ColorCooked2ColorRGB(cc))));
                    break;
                case 2://Monochrome Colo
                    lck.Add(ColorRGB.ColorRGB2ColorCooked(CColorManipulations.GetMonochromaticColor(ColorRGB.ColorCooked2ColorRGB(cc))));
                    break;
                case 3://Triadic Colors
                    foreach (ColorRGB rgb in CColorManipulations.GetTriadicColors(ColorRGB.ColorCooked2ColorRGB(cc)))
                    {
                        lck.Add(ColorRGB.ColorRGB2ColorCooked(rgb));
                    }
                    break;
                case 4://Analogous Color
                    foreach (ColorRGB rgb in CColorManipulations.GetAnalogousColors(ColorRGB.ColorCooked2ColorRGB(cc)))
                    {
                        lck.Add(ColorRGB.ColorRGB2ColorCooked(rgb));
                    }
                    break;
                case 5://Split Complements Color
                    foreach (ColorRGB rgb in CColorManipulations.GetSplitComplementsColors(ColorRGB.ColorCooked2ColorRGB(cc)))
                    {
                        lck.Add(ColorRGB.ColorRGB2ColorCooked(rgb));
                    }
                    break;
            }
        }

        private void panel1_PreviewMouseLeftButtonDown_1(object sender, MouseButtonEventArgs e)
        {
            //Button b = e.Source as Button;
            UCbutton ub = e.Source as UCbutton;
            //TextBox b = e.Source as TextBox;
            if (null == ub) return;
            //
            //ColorsCooked cc = b.Tag as ColorsCooked;
            ColorsCooked cc = ub.EssentialColor;
            if (null == cc) return;
            //
            List<ColorsCooked> lck = new List<ColorsCooked>();
            //
            add2LckColor(lck, cc, colorKind.SelectedIndex);
            //
            //
            if (inGradient)
            {
                if (ccGradient.Count > 100) return;//pomyłka?
                ccGradient.AddRange(lck);
                ub.IsLongDelay = true;
                return;
            }
            ub.IsLongDelay = false;
            //
            //
            string s = lck2String(lck, OutputFormat.FromKbd);
            if(""==s) return;
            //
            //animation(b);
            Clipboard.SetText(s, TextDataFormat.UnicodeText);
            //
            e.Handled = false;
        }


        private bool inGradient = false;
        private List<ColorsCooked> ccGradient = null;
        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            if (!inGradient)
            {
                gradientButton.IsEnabled = false;
                inGradient = true;
                ccGradient = new List<ColorsCooked>();
                //
                gradientButton.Content = "End Gradient";
                gradientButton.Background = Brushes.HotPink;
                //
                Clipboard.Clear();
                gradientButton.IsEnabled = true; ;
            }
            else
            {
                gradientButton.IsEnabled = false;
                if (ccGradient.Count >= 2)
                {
                    string s = gradientBrush(ccGradient);
                    Clipboard.SetText(s, TextDataFormat.UnicodeText);
                }
                gradientButton.Content = "Begin Gradient";
                gradientButton.Background = Brushes.Chartreuse;
                //
                inGradient = false;
                ccGradient = null;
                gradientButton.IsEnabled = true; ;
            }
        }

        private void Hyperlink_RequestNavigate_1(object sender, RequestNavigateEventArgs e)
        {
            Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri));
            e.Handled = true;
        }

        private void textSearch_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Escape)
            {
                if (CColors.ColorsTable.Count() != panel1.Children.Count) 
                {
                    laoadAllColors("");
                }
                e.Handled = true;
            }
            else if (e.Key == Key.Enter)
            {
                string srch = textSearch.Text.Trim();
                if ("" != srch)
                {
                    laoadAllColors(srch);
                }
                e.Handled = true;
            }
            return;
        }

        private void window1_Closed(object sender, EventArgs e)
        {
        }

    }
}
